package com.oraycn.esbasic.objectManagement;

import java.util.ArrayList; 

public class CircleQueue<T> {
    private ArrayList<T> array ;
    private int headIndex = 0;
    private int tailIndex = 0;
    private int capacity = 0;

    public CircleQueue(int size) {
        this.capacity = size ;
        this.array = new ArrayList<T>();
        for(int i=0;i<this.capacity;i++)
        {
            this.array.add(null) ;
        }
    }

    private int count = 0;
    public int getCount() {
        return count;
    }

    /**
     * 当装满后，再加入对象，则将最老的那个对象覆盖掉。
     * @param obj
     */
    public void Enqueue(T obj) {
        synchronized (this.array) {
            if (this.count == 0) {
                this.array.set(this.headIndex,obj);
                this.tailIndex = this.headIndex;
                ++this.count;
                return;
            }

            T head = this.array.get(this.headIndex);

            this.tailIndex = (this.tailIndex + 1) % this.capacity;
            this.array.set(this.tailIndex , obj);
            ++this.count;

            if (this.tailIndex == this.headIndex) {
                this.headIndex = (this.headIndex + 1) % this.capacity;
                --this.count;
            }
        }
    }

    public T Dequeue() {
        synchronized (this.array) {
            if (this.count == 0) {
                return null;
            }

            T obj = this.array.get(this.headIndex);
            this.array.set(this.headIndex, null);
            this.headIndex = (this.headIndex + 1) % this.capacity;
            --this.count;

            return obj;
        }
    }

    public T Peek() {
        synchronized (this.array) {
            if (this.count == 0) {
                return null;
            }

            T obj = this.array.get(this.headIndex);
            return obj;
        }
    }

    public void Clear() {
        synchronized (this.array) {
            this.count = 0;
        }
    }

    public ArrayList<T> GetAll()
    {
        synchronized (this.array)
        {
            ArrayList<T> list = new ArrayList<T>();
            for (int i = 0; i < this.count; i++)
            {
                list.add(this.array.get((this.headIndex + i) % this.capacity));
            }
            return list;
        }
    }

    public void Replace(ArrayList<T>  list)
    {
        synchronized (this.array) {
            this.Clear();
            for (T t : list) {
                this.Enqueue(t);
            }
        }
    }
}

//public class SortedArray<T> {
//
//
//}
